#!/usr/bin/env python

import sipy, sdpy
from voip_protocols import *
import md5, socket, random, string


def make_branch(len=10):
    return sip.BRANCH_MAGIC + compute_tag(len)

def make_via():
    import socket

    via = sipy.header(name=sipy.h_Vias)
    via.value = sipy.SIP_VERSION + '/' + 'UDP' + " localhost"
    via[sipy.p_rport] = ""
    via[sipy.p_branch] = make_branch()
    # some other shit here.
    #   set that fucker up.
    return via

def compute_call_id(len=16):
    m=""
    for i in range(len):
        m += string.hexdigits[random.randrange(0,15)]
    return m

def compute_tag(len=8):
    m=""
    for i in range(len):
        m += string.hexdigits[random.randrange(0,15)]
    return m

def make_request(method, target_uri, from_uri, contact_uri):
    msg = sipy.message(method=method, uri=target_uri)
    msg[sipy.h_To] = target_uri
    msg[sipy.h_Max_Forwards] = "70"
    msg[sipy.h_CSeq] = "1 " + method
    msg[sipy.h_From] = from_uri
    msg[sipy.h_From][sipy.p_tag] = compute_tag(4)
    msg[sipy.h_Contacts] = contact_uri
    msg[sipy.h_Call_ID] = compute_call_id()
    msg[sipy.h_Vias] = make_via()

    return msg

def make_register(to_uri, from_uri, contact_uri):
    msg = sipy.message(method=sipy.m_REGISTER, uri=to_uri)
    msg[sipy.h_Max_Forwards] = "70"
    msg[sipy.h_CSeq] = "1 " + sipy.m_REGISTER
    msg[sipy.h_From] = from_uri
    msg[sipy.h_From][sipy.p_tag] = compute_tag(4)
    msg[sipy.h_To] = to_uri
    msg[sipy.h_Call_ID] = compute_call_id()
    msg[sipy.h_Contacts] = contact_uri
    msg[sipy.h_Vias] = make_via()

    return msg

def make_invite(target_uri, from_uri, contact_uri):
    #return make_message(sipy.m_INVITE, target_uri, from_uri, contact_uri)
    return make_request(sipy.m_INVITE, target_uri, from_uri, contact_uri)

def make_response(msg, code, reason, contact_uri=None):
    rmsg = sipy.message(code=code, reason=reason)
    rmsg[h_From] = msg[h_From]
    rmsg[h_To] = msg[h_To]
    rmsg[h_Call_ID] = msg[h_Call_ID]
    rmsg[h_CSeq] = msg[h_CSeq]
    rmsg[h_Vias] = msg[h_Vias]

    if contact_uri:
        rmsg[h_Contacts] = contact_uri
    else:
        # auto generate a contact URI ... by magic
        pass

    if not rmsg[h_To].exists(p_tag):
        if code < 300 and code > 100:
            rmsg[h_To][p_tag] = compute_tag(4)
    if code >= 100 and code < 300 and msg.exists(h_Record_Routes):
        rmsg[h_Record_Routes] = msg[h_Record_Routes]

    return rmsg

import md5

def make_auth_md5response(username, password, realm, method, digest_uri, nonce,\
        qop=None, cnonce=None, cnonce_count=None):
    a1 = md5.new( username + COLON + realm + COLON + password )
    a2 = md5.new( method + COLON + digest_uri )

    r = md5.new( a1.hexdigest() + COLON + nonce + COLON )

    if qop:
        r.update( cnonce_count + COLON + cnonce + COLON + qop + COLON )

    r.update( a2.hexdigest() )

    return r.hexdigest()
